home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xmball / xmball.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  11KB  |  376 lines

  1. /*
  2. # X-BASED MASTERBALL(tm)
  3. #
  4. #  xmball.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 1: 94/09/15 Xt
  28. */
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #ifdef VMS
  33. #include <unixlib.h>
  34. #define getlogin cuserid
  35. #else
  36. #ifndef apollo
  37. #include <unistd.h>
  38. #endif
  39. #endif
  40. #include <X11/Intrinsic.h>
  41. #include <X11/StringDefs.h>
  42. #include <X11/Shell.h>
  43. #include <X11/cursorfont.h>
  44. #include "Mball.h"
  45. #include "mball.xbm"
  46.  
  47. #ifndef SCOREFILE
  48. #define SCOREFILE "/usr/games/lib/mball.scores"
  49. #endif
  50.  
  51. /* The following are in MballP.h also */
  52. #define MINWEDGES 2
  53. #define MAXWEDGES 8
  54. #define MINRINGS 1
  55.  
  56. #define MAXRINGS 6
  57. #define MAXRECORD 32767
  58. #define MAXPROGNAME 80
  59. #define MAXNAME 256
  60.  
  61. static void Initialize();
  62. static void CallbackMball();
  63.  
  64. static void PrintRecord();
  65. static int HandleSolved();
  66. static void PrintState();
  67. static void ReadRecords();
  68. static void WriteRecords();
  69.  
  70. static Arg arg[5];
  71. static int mballRecord[2][(MAXWEDGES - MINWEDGES) / 2 + 1]
  72.   [MAXRINGS - MINRINGS + 1];
  73. static int movesDsp = 0;
  74. static char progDsp[64] = "xmball";
  75. static char recordDsp[16] = "INF";
  76. static char messageDsp[128] = "Welcome";
  77. static char titleDsp[256] = "";
  78.  
  79. static void Usage()
  80. {
  81.   (void) fprintf(stderr, "usage: xmball\n");
  82.   (void) fprintf(stderr,
  83.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  84.   (void) fprintf(stderr,
  85.     "\t[-display [{host}]:[{vs}]] [-fg {color}] [-bg {color}]\n");
  86.   (void) fprintf(stderr,
  87.     "\t[-{border|bd} {color}] [-mono] [-{wedges {int}}] [-{rings {int}}]\n");
  88.   (void) fprintf(stderr,
  89.     "\t[-[no]orient] [-[no]practice] [-wedge{0|1|2|3|4|5|6|7} {color}]\n");
  90.   exit(1);
  91. }
  92.  
  93. static XrmOptionDescRec options[] = {
  94.   {"-fg",        "*mball.Foreground",    XrmoptionSepArg,    NULL},
  95.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  96.   {"-foreground",    "*mball.Foreground",    XrmoptionSepArg,    NULL},
  97.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  98.   {"-border",        "*mball.pieceBorder",    XrmoptionSepArg,    NULL},
  99.   {"-bd",        "*mball.pieceBorder",    XrmoptionSepArg,    NULL},
  100.   {"-mono",        "*mball.mono",        XrmoptionNoArg,        "TRUE"},
  101.   {"-wedges",        "*mball.wedges",    XrmoptionSepArg,    NULL},
  102.   {"-rings",        "*mball.rings",        XrmoptionSepArg,    NULL},
  103.   {"-orient",        "*mball.orient",    XrmoptionNoArg,        "TRUE"},
  104.   {"-noorient",        "*mball.orient",    XrmoptionNoArg,        "FALSE"},
  105.   {"-practice",        "*mball.practice",    XrmoptionNoArg,        "TRUE"},
  106.   {"-nopractice",    "*mball.practice",    XrmoptionNoArg,        "FALSE"},
  107.   {"-wedge0",        "*mball.wedgeColor0",    XrmoptionSepArg,    NULL},
  108.   {"-wedge1",        "*mball.wedgeColor1",    XrmoptionSepArg,    NULL},
  109.   {"-wedge2",        "*mball.wedgeColor2",    XrmoptionSepArg,    NULL},
  110.   {"-wedge3",        "*mball.wedgeColor3",    XrmoptionSepArg,    NULL},
  111.   {"-wedge4",        "*mball.wedgeColor4",    XrmoptionSepArg,    NULL},
  112.   {"-wedge5",        "*mball.wedgeColor5",    XrmoptionSepArg,    NULL},
  113.   {"-wedge6",        "*mball.wedgeColor6",    XrmoptionSepArg,    NULL},
  114.   {"-wedge7",        "*mball.wedgeColor7",    XrmoptionSepArg,    NULL},
  115. };
  116.  
  117. int main(argc, argv)
  118.   int argc;
  119.   char *argv[];
  120. {
  121.   Widget toplevel, mball; 
  122.  
  123.   toplevel = XtInitialize(argv[0], "Mball",
  124.     options, XtNumber(options), &argc, argv);
  125.   if (argc != 1)
  126.     Usage();
  127.  
  128.   XtSetArg(arg[0], XtNiconPixmap,
  129.     XCreateBitmapFromData(XtDisplay(toplevel),
  130.       RootWindowOfScreen(XtScreen(toplevel)),
  131.       (char *) mball_bits, mball_width, mball_height));
  132.   XtSetValues(toplevel, arg, 1);
  133.   mball = XtCreateManagedWidget("mball", mballWidgetClass, toplevel,
  134.     NULL, 0);
  135.   XtAddCallback(mball, XtNselectCallback, CallbackMball, NULL);
  136.   Initialize(mball);
  137.   XtRealizeWidget(toplevel);
  138.   XGrabButton(XtDisplay(mball), AnyButton, AnyModifier, XtWindow(mball),
  139.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  140.     GrabModeAsync, GrabModeAsync, XtWindow(mball),
  141.     XCreateFontCursor(XtDisplay(mball), XC_crosshair));
  142.   XtMainLoop();
  143.  
  144. #ifdef VMS
  145.   return 1;
  146. #else
  147.   return 0;
  148. #endif
  149. }
  150.  
  151. static void Initialize(w)
  152.   Widget w;
  153. {
  154.   int wedges, rings;
  155.   Boolean orient, practice;
  156.  
  157.   XtVaSetValues(w,
  158.     XtNstart, FALSE,
  159.     NULL);
  160.   XtVaGetValues(w,
  161.     XtNwedges, &wedges,
  162.     XtNrings, &rings,
  163.     XtNorient, &orient,
  164.     XtNpractice, &practice,
  165.     NULL);
  166.   ReadRecords();
  167.   PrintRecord(wedges, rings, orient, practice, recordDsp);
  168.   PrintState(XtParent(w), progDsp, wedges, rings, movesDsp,
  169.     recordDsp, messageDsp);
  170. }
  171.  
  172. static void CallbackMball(w, clientData, callData)
  173.   Widget w;
  174.   caddr_t clientData;
  175.   mballCallbackStruct *callData;
  176. {
  177.   int wedges, rings;
  178.   Boolean orient, practice, start;
  179.  
  180.   XtVaGetValues(w,
  181.     XtNwedges, &wedges,
  182.     XtNrings, &rings,
  183.     XtNorient, &orient,
  184.     XtNpractice, &practice,
  185.     XtNstart, &start,
  186.     NULL);
  187.   (void) strcpy(messageDsp, "");
  188.   switch (callData->reason) {
  189.     case MBALL_RESTORE:
  190.       if (practice)
  191.         (void) strcpy(recordDsp, "practice");
  192.       movesDsp = 0;
  193.       break;
  194.     case MBALL_RESET:
  195.       movesDsp = 0;
  196.       break;
  197.     case MBALL_AMBIGUOUS:
  198.       (void) strcpy(messageDsp, "Ambiguous move");
  199.       break;
  200.     case MBALL_ILLEGAL:
  201.       if (practice || start)
  202.         (void) strcpy(messageDsp, "Illegal move");
  203.       else
  204.         (void) strcpy(messageDsp, "Randomize to start");
  205.       break;
  206.     case MBALL_MOVED:
  207.       movesDsp++;
  208.       XtSetArg(arg[0], XtNstart, TRUE);
  209.       XtSetValues(w, arg, 1);
  210.       break;
  211.     case MBALL_CONTROL:
  212.       return;
  213.     case MBALL_SOLVED:
  214.       if (practice)
  215.         movesDsp = 0;
  216.       else { 
  217.         if (HandleSolved(movesDsp, wedges, rings, orient))
  218.           (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  219.         else
  220.           (void) strcpy(messageDsp, "Solved!");
  221.       }
  222.       XtSetArg(arg[0], XtNstart, FALSE);
  223.       XtSetValues(w, arg, 1);
  224.       break;
  225.     case MBALL_PRACTICE:
  226.       movesDsp = 0;
  227.       practice = !practice;
  228.       if (!practice)
  229.         (void) strcpy(messageDsp, "Randomize to start");
  230.       PrintRecord(wedges, rings, orient, practice, recordDsp);
  231.       XtSetArg(arg[0], XtNpractice, practice);
  232.       XtSetArg(arg[1], XtNstart, FALSE);
  233.       XtSetValues(w, arg, 2);
  234.       break;
  235.     case MBALL_RANDOMIZE:
  236.       movesDsp = 0;
  237.       XtSetArg(arg[0], XtNpractice, FALSE);
  238.       XtSetArg(arg[1], XtNstart, FALSE);
  239.       XtSetValues(w, arg, 2);
  240.       break; 
  241.     case MBALL_DEC:
  242.       movesDsp = 0;
  243.       rings--;
  244.       PrintRecord(wedges, rings, orient, practice, recordDsp);
  245.       XtSetArg(arg[0], XtNrings, rings);
  246.       XtSetValues(w, arg, 1);
  247.       break;
  248.     case MBALL_ORIENT:
  249.       movesDsp = 0;
  250.       orient = !orient;
  251.       PrintRecord(wedges, rings, orient, practice, recordDsp);
  252.       XtSetArg(arg[0], XtNorient, orient);
  253.       XtSetValues(w, arg, 1);
  254.       break;
  255.     case MBALL_INC:
  256.       movesDsp = 0;
  257.       rings++;
  258.       PrintRecord(wedges, rings, orient, practice, recordDsp);
  259.       XtSetArg(arg[0], XtNrings, rings);
  260.       XtSetValues(w, arg, 1);
  261.       break;
  262.     case MBALL_WEDGE2:
  263.     case MBALL_WEDGE4:
  264.     case MBALL_WEDGE6:
  265.     case MBALL_WEDGE8:
  266.       movesDsp = 0;
  267.       wedges = 2 * (callData->reason - MBALL_WEDGE2) + MINWEDGES;
  268.       PrintRecord(wedges, rings, orient, practice, recordDsp);
  269.       XtSetArg(arg[0], XtNwedges, wedges);
  270.       XtSetValues(w, arg, 1);
  271.       break;
  272.     case MBALL_COMPUTED:
  273.       XtSetArg(arg[0], XtNstart, FALSE);
  274.       XtSetValues(w, arg, 1);
  275.       break;
  276.     case MBALL_UNDO:
  277.       movesDsp--;
  278.       XtSetArg(arg[0], XtNstart, TRUE);
  279.       XtSetValues(w, arg, 1);
  280.       break;
  281.   }
  282.   PrintState(XtParent(w), progDsp, wedges, rings, movesDsp,
  283.     recordDsp, messageDsp);
  284. }
  285.  
  286. static void PrintRecord(wedges, rings, orient, practice, record)
  287.   int wedges, rings;
  288.   Boolean orient, practice;
  289.   char *record;
  290. {
  291.   int i = (orient) ? 1 : 0;
  292.   int w = (wedges - MINWEDGES) / 2;
  293.   int r = rings - MINRINGS;
  294.  
  295.   if (practice)
  296.     (void) strcpy(record, "practice");
  297.   else if (rings > MAXRINGS)
  298.     (void) strcpy(record, "NOT RECORDED");
  299.   else if (mballRecord[i][w][r] >= MAXRECORD)
  300.     (void) strcpy(record, "NEVER");
  301.   else
  302.     (void) sprintf(record, "%d", mballRecord[i][w][r]);
  303. }
  304.  
  305. static int HandleSolved(counter, wedges, rings, orient)
  306.   int counter, wedges, rings;
  307.   Boolean orient;
  308. {
  309.   int i = (orient) ? 1 : 0;
  310.   int w = (wedges - MINWEDGES) / 2;
  311.   int r = rings - MINRINGS;
  312.  
  313.   if (rings <= MAXRINGS && counter < mballRecord[i][w][r]) {
  314.     mballRecord[i][w][r] = counter;
  315.     if (orient && mballRecord[i][w][r] < mballRecord[!i][w][r])
  316.       mballRecord[!i][w][r] = counter;
  317.     WriteRecords();
  318.     (void) sprintf(recordDsp, "%d", counter);
  319.     return TRUE;
  320.   }
  321.   return FALSE;
  322. }
  323.  
  324. static void PrintState(w, prog, wedges, rings, moves, record, message)
  325.   Widget w;
  326.   char *prog, *record, *message;
  327.   int wedges, rings, moves;
  328. {
  329.   (void) sprintf(titleDsp, "%s.%d: %d@ (%d/%s) - %s", prog, wedges, rings,
  330.            moves, record, message);
  331.   XtSetArg(arg[0], XtNtitle, titleDsp);
  332.   XtSetValues(w, arg, 1);
  333. }
  334.  
  335. static void ReadRecords()
  336. {
  337.   FILE *fp;
  338.   int i, j, n, orient;
  339.  
  340.   for (orient = 0; orient < 2; orient++)
  341.     for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++)
  342.       for (j = 0; j < MAXRINGS - MINRINGS + 1; j++)
  343.         mballRecord[orient][i][j] = MAXRECORD;
  344.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  345.     (void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
  346.   else {
  347.     for (orient = 0; orient < 2; orient++)
  348.       for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++)
  349.         for (j = 0; j < MAXRINGS - MINRINGS + 1; j++) {
  350.           (void) fscanf(fp, "%d", &n);
  351.           mballRecord[orient][i][j] = n;
  352.         }
  353.     (void) fclose(fp);
  354.   }
  355. }
  356.  
  357. static void WriteRecords()
  358. {
  359.   FILE *fp;
  360.   int i, j, orient;
  361.  
  362.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  363.     (void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
  364.   else {
  365.     for (orient = 0; orient < 2; orient++) {
  366.       for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++) {
  367.         for (j = 0; j < MAXRINGS - MINRINGS + 1; j++)
  368.           (void) fprintf(fp, "%d ", mballRecord[orient][i][j]);
  369.         (void) fprintf(fp, "\n");
  370.       }
  371.       (void) fprintf(fp, "\n");
  372.     }
  373.     (void) fclose(fp);
  374.   }
  375. }
  376.